首页>>百科常识

请教:在OPENGL中添加光源后有光晕,如何处理?

今天宠物迷的小编给各位宠物饲养爱好者分享opengl 效果的宠物知识,其中也会对请教:在OPENGL中添加光源后有光晕,如何处理?(opengl添加点光源)进行专业的解释,如果能碰巧解决你现在面临的宠物相关问题,别忘了关注本站哦,现在我们开始吧!

请教:在OPENGL中添加光源后有光晕,如何处理?

bloom效果即可,过程如下:
首先将场景渲染到纹理,然后将纹理downSample到1/4或1/16大小(就是缩小纹理,为了加快模糊计算)
然后将纹理模糊后放大到原大小,按一定比例混合到场景中去就有光晕效果了.

请教:在OPENGL中添加光源后有光晕,如何处理?

在黑暗中这种效果是如何**出来的

图片的锐度和质感都不高,不是用高级相机及镜头拍摄的,一般手机卡片机就可以了。
首先人穿黑衣服,在黑暗处,然后用路灯或者台灯直射脸部,拍摄时对焦测光对准脸部,把iso调高,直接拍摄就可以了。
又或者用离机引闪闪光灯,在高处同步闪光,也能有这种效果。
至于后期调整,只需把对比度稍微调高就可以了。
这种照片不难拍摄,只是光线对比度高而已。

请教如何用OpenGL实现两个窗口同步显示不同内容的图片动画

需要开两个线程,每个线程中采用不同的OpenGL context显示不同的内容,然后通过信号量同步

倾家荡产悬赏高人解答一极度高深的问题:骨骼动画的几种蒙皮算法的比较!

最最节省时间的肯定还是LBS,而效果最好的是对偶四元数方法,对偶四元数法不会出现线性方法带来的一些在扭曲时的塌陷问题,避免调节权限等,多了不说了,对偶四元数法很新,建议去参考下论文《skinning with dual quaternions》,可以交流一下子

什么是OpenGL?在3D游戏里有什么作用?

  简单的说OpenGL是个3D标准 不知道你说的提高数值是什么意思?
  OpenGL是个专业的3D程序接口,是一个功能强大,调用方便的底层3D图形库。OpenGL的前身是SGI公司为其图形工作站开发的IRIS GL。IRIS GL是一个工业标准的3D图形软件接口,功能虽然强大但是移植性不好,于是SGI公司便在IRIS GL的基础上开发了OpenGL。OpenGL的英文全称是“Open Graphics Library”,顾名思义,OpenGL便是“开放的图形程序接口”。虽然DirectX在家用市场全面领先,但在专业高端绘图领域,OpenGL是不能被取代的主角。

  OpenGL是个与.硬件无关的软件接口,可以在不同的平台如Windows 95、Windows NT、Unix、Linux、MacOS、OS/2之间进行移植。因此,支持OpenGL的软件具有很好的移植性,可以获得非常广泛的应用。由于OpenGL是3D图形的底层图形库,没有提供几何实体图元,不能直接用以描述场景。但是,通过一些转换程序,可以很方便地将AutoCAD、3DS等3D图形设计软件制作的DFX和3DS模型文件转换成OpenGL的顶点数组。

  在OpenGL的基础上还有Open Inventor、Cosmo3D、Optimizer等多种高级图形库,适应不同应用。其中,Open Inventor应用最为广泛。该软件是基于OpenGL面向对象的工具包,提供创建交互式3D图形应用程序的对象和方法,提供了预定义的对象和用于交互的事件处理模块,创建和编辑3D场景的高级应用程序单元,有打印对象和用其它图形格式交换数据的能力。

  OpenGL的发展一直处于一种较为迟缓的态势,每次版本的提高新增的技术很少,大多只是对其中部分做出修改和完善。1992年7月,SGI公司发布了OpenGL的1.0版本,随后又与微软公司共同开发了Windows NT版本的OpenGL,从而使一些原来必须在高档图形工作站上运行的大型3D图形处理软件也可以在微机上运用。1995年OpenGL的1.1版本面市,该版本比1.0的性能有许多提高,并加入了一些新的功能。其中包括改进打印机支持,在增强元文件中包含OpenGL的调用,顶点数组的新特性,提高顶点位置、法线、颜色、色彩指数、纹理坐标、多边形边缘标识的传输速度,引入了新的纹理特性等等。OpenGL 1.5又新增了“OpenGL Shading Language”,该语言是“OpenGL 2.0”的底核,用于着色对象、顶点着色以及片断着色技术的扩展功能。

  OpenGL 2.0标准的主要制订者并非原来的SGI,而是逐渐在ARB中占据主动地位的3Dlabs。2.0版本首先要做的是与旧版本之间的完整兼容性,同时在顶点与像素及内存管理上与DirectX共同合作以维持均势。OpenGL 2.0将由OpenGL 1.3的现有功能加上与之完全兼容的新功能所组成(如图一)。借此可以对在ARB停滞不前时代各家推出的各种纠缠不清的扩展指令集做一次彻底的精简。此外,硬件可编程能力的实现也提供了一个更好的方法以整合现有的扩展指令。

  目前,随着DirectX的不断发展和完善,OpenGL的优势逐渐丧失,至今虽然已有3Dlabs提倡开发的2.0版本面世,在其中加入了很多类似于DirectX中可编程单元的设计,但厂商的用户的认知程度并不高,未来的OpenGL发展前景迷茫。

如何使用Android中的OpenGL ES媒体效果

  设置OpenGL ES环境

  创建GLSurfaceView
  为了显示OpenGL的图形,你需要使用GLSurfaceView类,就像其他任何的View子类意义,你可以将它添加到你的Activity或Fragment之上,通过在布局xml文件中定义或者在代码中创建实例。

  在本次的教程中,我们使用GLSurfaceView作为唯一的View在我们的Activity中,因此,为了简便,我们在代码中创建GLSurfaceView的实例并将其传入setContentView中,这样它将会填充你的整个手机屏幕。Activity中的onCreate方法如下:

  protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  GLSurfaceView view = new GLSurfaceView(this);
  setContentView(view);
  }
  因为媒体效果的框架仅仅支持OpenGL ES2.0及以上的版本,所以在setEGLContextClientVersion 方法中传入2;

  view.setEGLContextClientVersion(2);
  为了确保GLSurfaceView仅仅在必要的时候进行渲染,我们在setRenderMode 方法中进行设置:

  view.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
  创建Renderer
  Renderer负责渲染GLSurfaceView中的内容。

  创建类实现接口GLSurfaceView.Renderer,在这里我们打算将这个类命名为EffectsRenderer,添加构造函数并覆写接口中的抽象方法,如下:

  public class EffectsRenderer implements GLSurfaceView.Renderer {
  
  public EffectsRenderer(Context context){
  super();
  }
  
  @Override
  public void onSurfaceCreated(GL10 gl, EGLConfig config) {
  }
  
  @Override
  public void onSurfaceChanged(GL10 gl, int width, int height) {
  }
  
  @Override
  public void onDrawFrame(GL10 gl) {
  }
  }
  回到Activity中调用setRenderer方法,让GLSurfaceView使用我们创建的Renderer:

  view.setRenderer(new EffectsRenderer(this));
  编写Manifest文件
  如果你想要发布你的App到谷歌商店,在AndroidManifest.xml文件中添加如下语句:

  
  这会确保你的app只能被安装在支持OpenGL ES2.0的设备之上。现在OpenGL环境准备完毕。

  创建一个OpenGL平面

  定义顶点
  GLSurfaceView是不能直接显示一张照片的,照片首先应该被转化为纹理,应用在OpenGL square之上。在本次教程中,我将创建一个2D平面,并且具有4个顶点。为了简单,我将使用一个长方形,现在,创建一个新的类Square,用它来代表形状。


  public class Square {
  
  }
  默认的OpenGL系统的坐标系中的**是在中心,因此4个角的坐标可以表示为:

  左下角: (-1, -1) 右下角:(1, -1) 右上角:(1, 1) 左上角:(-1, 1)
  我们使用OpenGL绘制的所有的物体都应该是由三角形决定的,为了画一个方形,我们需要两个具有一条公共边的三角形,那意味着这些三角形的坐标应该是:

  triangle 1: (-1, -1), (1, -1), 和 (-1, 1) triangle 2: (1, -1), (-1, 1), 和 (1, 1)
  创建一个float数组来代表这些顶点:

  private float vertices[] = {
  -1f, -1f,
  1f, -1f,
  -1f, 1f,
  1f, 1f,
  };
  为了在square上定位纹理,需要确定纹理的顶点坐标,创建另一个数组来表示纹理顶点的坐标:

  private float textureVertices[] = {
  0f,1f,
  1f,1f,
  0f,0f,
  1f,0f
  };
  创建缓冲区
  这些坐标数组应该被转变为缓冲字符(byte buffer)在OpenGL可以使用之前,接下来进行定义:

  private FloatBuffer verticesBuffer;
  private FloatBuffer textureBuffer;
  在initializeBuffers方法中去初始化这些缓冲区:使用ByteBuffer.allocateDirect来创建缓冲区,因为float是4个字节,那么我们需要的byte数组的长度应该为float的4倍。

  下面使用ByteBuffer.nativeOrder方法来定义在底层的本地平台上的byte的顺序。使用asFloatBuffer方法将ByteBuffer转化为FloatBuffer,在FloatBuffer被创建后,我们调用put方法来将float数组放入缓冲区,最后,调用position方法来保证我们是由缓冲区的开头进行读取。

  创建着色器
  着色器只不过是简单的运行在GPU中的每个单独的顶点的C程序,在本次教程中,我们使用两种着色器:顶点着色器和片段着色器。
  顶点着色器的代码:

  attribute vec4 aPosition;
  attribute vec2 aTexPosition;
  varying vec2 vTexPosition;
  void main() {
  gl_Position = aPosition;
  vTexPosition = aTexPosition;
  };
  片段着色器的代码

  precision mediump float;
  uniform sampler2D uTexture;
  varying vec2 vTexPosition;
  void main() {
  gl_FragColor = texture2D(uTexture, vTexPosition);
  };
  如果你了解OpenGL,那么这段代码对你来说是熟悉的,如果你不能理解这段代码,你可以参考OpenGL documentation。这里有一个简明扼要的解释:

  顶点着色器负责绘制单个顶点。aPosition是一个变量被绑定到FloatBuffer上,包含着这些顶点的坐标。相似的,aTexPosition 是一个变量被绑定到FloatBuffer上,包含着纹理的坐标。gl_Position 是一个在OpenGL中创建的变量,代表每一个顶点的位置,vTexPosition是一个数组变量,它的值被传递到片段着色器中。

  在本教程中,片段着色器负责square的着色。它使用texture2D方法从纹理中拾取颜色,并且使用一个在OpenGL中被创建的变量gl_FragColor将颜色分配到片段。

  在该类中,着色器的代码应该被转化为String。

  创建程序
  创建新的方法initializeProgram来创建一个编译和链接着色器的OpenGL程序。

  使用glCreateShader创建一个着色器对象,并且返回以int为表示形式的指针。为了创建顶点着色器,传递GL_VERTEX_SHADER给它。相似的,为了创建一个片段着色器,传递GL_FRAGMENT_SHADER给它。下面使用glShaderSource方法关联相对应的着色器代码到着色器上。使用glCompileShader编译着色器代码。
  在编译了着色器的代码后,创建一段新的的程序glCreateProgram,与glCreateShader相似,它也返回一个以int为表示形式的指针。调用glAttachShader方法附着着色器到程序中,最后,调用glLinkProgram进行链接。

  你可能会发现,OpenGL的方法(以gl开头的)都是在GLES20类中,这是因为我们使用的是OpenGL ES2.0,如果我们使用更高的版本,就会用到这些类:GLES30,GLES31。

  画出形状
  现在定义draw方法来利用我们之前定义的点和着色器进行绘制。

  下面是你需要做的:
  1.使用glBindFramebuffer方法创建一个帧缓冲对象(FBO)
  2.调用glUseProgram创建程序,就像之前所提
  3.传递GL_BLEND给glDisable方法,在渲染过程中禁用颜色的混合。
  4.调用glGetAttribLocation得到变量aPosition和aTexPosition的句柄
  5.使用glVertexAttribPointer连接aPosition和aTexPosition的句柄到各自的verticesBuffer和textureBuffer
  6.使用glBindTexture方法绑定纹理(作为draw方法的参数传入)到片段着色器上
  7.调用glClear方法清空GLSurfaceView的内容
  8.最后,使用glDrawArrays方法画出两个三角形(也就是方形)

  public void draw(int texture){
  GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
  GLES20.glUseProgram(program);
  GLES20.glDisable(GLES20.GL_BLEND);
  
  int positionHandle = GLES20.glGetAttribLocation(program, aPosition);
  int textureHandle = GLES20.glGetUniformLocation(program, uTexture);
  int texturePositionHandle = GLES20.glGetAttribLocation(program, aTexPosition);
  
  GLES20.glVertexAttribPointer(texturePositionHandle, 2, GLES20.GL_FLOAT, false, 0, textureBuffer);
  GLES20.glEnableVertexAttribArray(texturePositionHandle);
  
  GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
  GLES20.glUniform1i(textureHandle, 0);
  
  GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 0, verticesBuffer);
  GLES20.glEnableVertexAttribArray(positionHandle);
  
  GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
  GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
  }
  在构造函数中添加初始化方法:

  public Square(){
  initializeBuffers();
  initializeProgram();
  }
  渲染OpenGL平面和纹理

  现在我们的渲染器什么也没做,我们需要改变它来渲染我们在前面创造的平面。

  首先,让我们创建一个Bitmap,添加一张照片到res/drawable文件夹之下,我把它命名为forest.jpg,使用BitmapFactory将照片转化为Bitmap。另外将照片的尺寸存储下来。

  改变EffectsRenderer的构造函数如下,

  private Bitmap photo;
  private int photoWidth, photoHeight;
  public EffectsRenderer(Context context){
  super();
  photo = BitmapFactory.decodeResource(context.getResources(), R.drawable.forest);
  photoWidth = photo.getWidth();
  photoHeight = photo.getHeight();
  }
  创建一个新的方法generateSquare,将Bitmap转化为纹理,并且出初始化Square对象,你也需要一个数组来保存对纹理的引用,使用glGenTextures来初始化这个数组,glBindTexture方法来在位置0激活纹理。
  现在,调用glTexParameteri设置不同的级别,决定纹理被怎样渲染。

  设置GL_TEXTURE_MIN_FILTER(修正功能),GL_TEXTURE_MAG_FILTER(放大功能)给GL_LINEAR,确保图片是平滑的在它被拉伸的时候。

  设置GL_TEXTURE_WRAP_S和GL_TEXTURE_WRAP_T给GL_CLAMP_TO_EDGE,保证纹理不会重复。

  最后调用texImage2D方法将Bitmap放置到纹理中,实现方法如下:

  private int textures[] = new int[2];
  private Square square;
  
  private void generateSquare(){
  GLES20.glGenTextures(2, textures, 0);
  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
  
  GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
  GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
  GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
  GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
  
  GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, photo, 0);
  square = new Square();
  }
  当GLSurfaceView的尺寸发生改变时,onSurfaceChanged方法被调用,这时我们需要调用glViewPort确认新的尺寸。调用glClearColor使其变为黑色,接着调用generateSquare重新初始化纹理和平面。

  @Override
  public void onSurfaceChanged(GL10 gl, int width, int height) {
  GLES20.glViewport(0,0,width, height);
  GLES20.glClearColor(0,0,0,1);
  generateSquare();
  }
  最后在onDrawFrame调用draw方法:

 
  @Override
  public void onDrawFrame(GL10 gl) {
  square.draw(textures[0]);
  }
  最后,你可以运行程序,在手机上看到你选择的图片被渲染出来

本文由宠物迷 百科常识栏目发布,非常欢迎各位朋友分享到个人朋友圈,但转载请说明文章出处“请教:在OPENGL中添加光源后有光晕,如何处理?

标签:宠物爱好